<template>
  <teleport to="body">
    <div class="modal-container" v-if="isShow" @click.self="cancel('mask')">
      <div class="modal-content" :style="{ width: `${width}%` }">
        <div class="modal-header">
          <slot name="header">
            <h5 class="modal-title">{{ title }}</h5>
          </slot>
          <button
            v-if="closable"
            type="button"
            class="btn-close"
            @click.stop="cancel()"
          ></button>
        </div>
        <div class="modal-body">
          <slot></slot>
        </div>
        <div class="modal-footer">
          <slot name="footer">
            <button
              type="button"
              class="btn btn-secondary"
              @click.stop="cancel()"
            >
              {{ cancelText }}
            </button>
            <button
              type="button"
              class="btn btn-primary"
              @click.stop="confirm()"
            >
              {{ confirmText }}
            </button>
          </slot>
        </div>
      </div>
    </div>
  </teleport>
</template>

<script lang="ts">
import { defineComponent, computed } from 'vue'

export default defineComponent({
  name: 'Modal',
  props: {
    modelValue: {
      type: Boolean,
      required: true
    },
    width: {
      type: Number,
      default: 40
    },
    title: {
      type: String
    },
    closable: {
      type: Boolean,
      default: true
    },
    maskClosable: {
      type: Boolean,
      default: true
    },
    cancelText: {
      type: String,
      default: '取消'
    },
    confirmText: {
      type: String,
      default: '确定'
    }
  },
  emits: ['update:modelValue', 'cancel', 'confirm'],
  setup (props, context) {
    const isShow = computed<boolean>({
      get () {
        return props.modelValue
      },
      set (v) {
        context.emit('update:modelValue', v)
      }
    })

    const cancel = (type?: string) => {
      if (type === 'mask' && !props.maskClosable) {
        return
      }
      isShow.value = false
      context.emit('cancel')
    }

    const confirm = () => {
      context.emit('confirm')
    }

    return {
      isShow,
      cancel,
      confirm
    }
  }
})
</script>

<style scoped>
.modal-container {
  position: fixed;
  left: 0;
  top: 0;
  width: 100vw;
  height: 100vh;
  z-index: 99;
  background-color: rgba(0, 0, 0, 0.7);
  display: flex;
  justify-content: center;
  align-items: center;
}
</style>
